# Version: 2.0.5.11
# 作者：Michael
# 功能：使用NeoPixel点阵屏显示数字
# 1.0.73 尝试反色显示
# 1.0.74 取消反色显示
# 20250926起，升级为双排
from machine import Pin
from neopixel import NeoPixel
import time
import ntptime



# 初始化NeoPixel点阵屏 6*48
pin = Pin(14, Pin.OUT)  # 使用GPIO14引脚
np = NeoPixel(pin, 288*2)  # 6x48点阵屏，共288个LED

# 定义颜色数组
color = [
    0xFF0000,  # 红色
    0xFF8500,  # 橙色
    0xFFFF00,  # 黄色
    0x00FF00,  # 绿色
    0x00FFFF,  # 青色
    0x0000FF,  # 蓝色
    0x800080,  # 紫色
    0x808080,  # 灰色
    0xFFFFFF,  # 白色
    0x000000,  # 黑色
]

# 定义点阵屏的宽度和高度
WIDTH = 48
HEIGHT = 6*2

num = [
    0, 0, 0, 0, 0, 10, 0, 4, 17, 14, 10, 0, 0, 14, 17, 27, 31, 31, 14, 4, 0, 0, 0, 0, 0, 0, 4, 10, 4, 14, 4, 14, 14, 4, 14, 0, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 4, 10, 4, 0, 0, 0, 0, 0, 0, 30, 28, 31, 21, 7, 5, 13, 31, 12, 4, 20, 22, 31, 6, 4, 15, 10, 10, 10, 5, 21, 14, 27, 14, 21, 4, 12, 28, 12, 4, 4, 6, 7, 6, 4, 4, 14, 4, 14, 4, 10, 10, 10, 0, 10, 12, 11, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 31, 31, 0, 0, 0, 0, 0, 4, 14, 21, 4, 4, 4, 4, 21, 14, 4, 4, 8, 31, 8, 4, 4, 2, 31, 2, 4, 0, 2, 2, 30, 0, 0, 14, 14, 14, 0, 4, 14, 31, 0, 0, 0, 0, 31, 14, 4, 0, 0, 0, 0, 0, 4, 4, 4, 0, 4, 10, 10, 0, 0, 0, 10, 31, 10, 31, 10, 31, 5, 31, 20, 31, 17, 8, 4, 2, 17, 6, 9, 22, 9, 22, 8, 4, 0, 0, 0, 8, 4, 4, 4, 8, 2, 4, 4, 4, 2, 21, 14, 31, 14, 21, 0, 4, 14, 4, 0, 0, 0, 0, 4, 2, 0, 0, 14, 0, 0, 0, 0, 0, 0, 2, 8, 4, 4, 4, 2, 14, 25, 21, 19, 14, 4, 6, 4, 4, 14, 14, 8, 14, 2, 14, 14, 8, 12, 8, 14, 2, 2, 10, 14, 8, 14, 2, 14, 8, 14, 6, 2, 14, 10, 14, 14, 8, 12, 8, 8, 14, 10, 14, 10, 14, 14, 10, 14, 8, 14, 0, 4, 0, 4, 0, 0, 4, 0, 4, 2, 8, 4, 2, 4, 8, 0, 14, 0, 14, 0, 2, 4, 8, 4, 2, 14, 17, 12, 0, 4, 14, 9, 5, 1, 14, 6, 9, 17, 31, 17, 7, 9, 15, 17, 15, 14, 17, 1, 17, 14, 15, 25, 17, 17, 15, 31, 1, 15, 1, 31, 31, 1, 15, 1, 1, 14, 1, 25, 17, 14, 9, 17, 31, 17, 17, 14, 4, 4, 4, 14, 12, 8, 8, 10, 14, 9, 5, 3, 5, 9, 1, 1, 1, 1, 15, 17, 27, 21, 17, 17, 17, 19, 21, 25, 17, 14, 25, 17, 17, 14, 7, 9, 7, 1, 1, 14, 17, 17, 25, 30, 7, 9, 7, 5, 9, 30, 1, 14, 16, 15, 31, 4, 4, 4, 4, 9, 17, 17, 17, 14, 10, 10, 10, 10, 4, 9, 17, 21, 21, 10, 17, 10, 4, 10, 17, 17, 10, 4, 4, 4, 31, 8, 4, 2, 31, 12, 4, 4, 4, 12, 2, 4, 4, 4, 8, 6, 4, 4, 4, 6, 4, 10, 0, 0, 0, 0, 0, 0, 0, 14, 4, 8, 0, 0, 0, 6, 9, 17, 31, 17, 7, 9, 15, 17, 15, 14, 17, 1, 17, 14, 15, 25, 17, 17, 15, 31, 1, 15, 1, 31, 31, 1, 15, 1, 1, 14, 1, 25, 17, 14, 9, 17, 31, 17, 17, 14, 4, 4, 4, 14, 12, 8, 8, 10, 14, 18, 10, 6, 10, 18, 1, 1, 1, 1, 15, 17, 27, 21, 17, 17, 17, 19, 21, 25, 17, 14, 25, 17, 17, 14, 7, 9, 7, 1, 1, 14, 17, 17, 25, 30, 7, 9, 7, 5, 9, 30, 1, 14, 16, 15, 31, 4, 4, 4, 4, 9, 17, 17, 17, 14, 10, 10, 10, 10, 4, 9, 17, 21, 21, 10, 17, 10, 4, 10, 17, 17, 10, 4, 4, 4, 31, 8, 4, 2, 31, 12, 4, 2, 4, 12, 4, 4, 4, 4, 4, 6, 4, 8, 4, 6, 10, 5, 0, 0, 0, 0, 4, 10, 10, 14, 0, 0, 0, 0, 0, 10, 0, 10, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 14, 10, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 17, 17, 17, 31, 0, 14, 10, 14, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 14, 10, 14, 0, 0, 0, 0, 0, 0, 10, 0, 14, 10, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 14, 10, 14, 0, 0, 0, 0, 0, 3, 25, 11, 9, 11, 28, 23, 21, 21, 29, 0, 3, 1, 1, 1, 10, 0, 14, 10, 14, 10, 0, 10, 10, 14, 0, 0, 0, 0, 31, 12, 18, 7, 2, 31, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 6, 17, 14, 0, 0, 28, 4, 4, 0, 0, 7, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 18, 9, 18, 4, 4, 9, 18, 9, 4, 0, 10, 0, 10, 0, 10, 21, 10, 21, 10, 21, 10, 21, 10, 21, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 7, 4, 7, 4, 10, 10, 11, 10, 10, 0, 0, 15, 10, 10, 0, 7, 4, 7, 4, 10, 11, 8, 11, 10, 10, 10, 10, 10, 10, 0, 15, 8, 11, 10, 10, 11, 8, 15, 0, 10, 10, 15, 0, 0, 4, 7, 4, 7, 0, 0, 0, 7, 4, 4, 4, 4, 28, 0, 0, 4, 4, 31, 0, 0, 0, 0, 31, 4, 4, 4, 4, 28, 4, 4, 0, 0, 31, 0, 0, 4, 4, 31, 4, 4, 4, 28, 4, 28, 4, 10, 10, 26, 10, 10, 10, 26, 2, 30, 0, 0, 30, 2, 26, 10, 10, 27, 0, 31, 0, 0, 31, 0, 27, 10, 10, 26, 2, 26, 10, 0, 31, 0, 31, 0, 10, 27, 0, 27, 10, 4, 31, 0, 31, 0, 10, 10, 31, 0, 0, 0, 31, 0, 31, 4, 0, 0, 31, 10, 10, 10, 10, 30, 0, 0, 4, 28, 4, 28, 0, 0, 28, 4, 28, 4, 0, 0, 30, 10, 10, 10, 10, 31, 10, 10, 4, 31, 4, 31, 4, 4, 4, 7, 0, 0, 0, 0, 28, 4, 4, 31, 31, 31, 31, 31, 0, 0, 31, 31, 31, 3, 3, 3, 3, 3, 24, 24, 24, 24, 24, 31, 31, 31, 0, 0, 0, 0, 0, 0, 0, 6, 9, 13, 17, 13, 0, 0, 0, 0, 0, 14, 17, 17, 17, 14, 0, 4, 10, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 10, 4, 0, 0, 0, 0, 0, 0, 14, 17, 17, 10, 27, 7, 1, 6, 9, 6, 0, 14, 31, 14, 0, 16, 14, 10, 14, 1, 12, 2, 14, 2, 12, 6, 9, 9, 9, 9, 14, 0, 14, 0, 14, 4, 14, 4, 0, 14, 2, 4, 8, 4, 14, 8, 4, 2, 4, 14, 8, 20, 4, 4, 4, 4, 4, 4, 5, 2, 4, 0, 14, 0, 4, 10, 5, 0, 10, 5, 4, 14, 4, 0, 0, 0, 14, 14, 14, 0, 0, 0, 4, 0, 0, 24, 8, 11, 10, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
num[55*5+2]=8  #调整7的造型
num[54*5+0]=14 #调整6的造型
num[52*5+0]=10 #调整4的造型
num[52*5+1]=10 #调整4的造型
num[52*5+2]=14 #调整4的造型
num[52*5+3]=8  #调整4的造型
num[51*5+2]=14 #调整3的造型
num[48*5+0]=14  #调整0的造型
num[48*5+1]=10  #调整0的造型
num[48*5+2]=10  #调整0的造型
num[48*5+3]=10  #调整0的造型
num[48*5+4]=14  #调整0的造型
def get_bit(value, index):
    return (value >> index) & 1


# 定义点阵屏的映射函数
def point1(x, y, c):
    # 计算索引 n
    n = y * 48 + (x if y & 1 == 0 else 47 - x)
    # 将值 c 赋给 np[n]
    np[n] = c
    #np.write()
def point2(x, y, c):
    #if y % 2 == 0:
    #    n = y * WIDTH + x
    #else:
    #    n = y * WIDTH + (WIDTH - 1 - x)
    n = y * WIDTH + (x if y & 1 == 0 else WIDTH  -1 - x)
    np[n] = (c >> 16, (c >> 8) & 0xFF, c & 0xFF)
    #np.write()

# 定义彩虹颜色轮函数
def wheel(pos):
    if pos < 85:
        return (pos * 3, 255 - pos * 3, 0)
    elif pos < 170:
        pos -= 85
        return (255 - pos * 3, 0, pos * 3)
    else:
        pos -= 170
        return (0, pos * 3, 255 - pos * 3)

# 初始化
def setup(r,g,b):
    np.fill((r, g, b))  # 清空屏幕
    np.write()
    time.sleep(1)

# 主循环
def loop():
    # 模式1：逐点绘制
    i=0
    for x in range(WIDTH):
        for y in range(HEIGHT):
            point2(x, y, color[i % (len(color)-1)])
            np.write()
            time.sleep(0.05)
            i+=1
    setup(0,0,0)
    # 模式2：逐行绘制
    for x in range(WIDTH):
        for y in range(HEIGHT):
            point2(x, y, color[x % (len(color)-1)])
        np.write()
        time.sleep(0.5)
    setup(0,0,0)
    # 模式3：分列彩虹效果
    for i in range(0, 256, 3):
        for x in range(WIDTH):
            for y in range(HEIGHT):
                #r, g, b = wheel((x * 256 // WIDTH + i) % 256)
                #np[x * HEIGHT + y] = (r, g, b)
                point1(x, y, wheel((x * 256 // WIDTH + i) & 255))
        np.write()
        #time.sleep(0.001)
        '''
    # 模式4：整体彩虹效果
    for i in range(256):
        for x in range(WIDTH):
            for y in range(HEIGHT):
                #r, g, b = wheel((x * 256 // WIDTH + i) % 256)
                #np[x * HEIGHT + y] = (r, g, b)
                
        np.write()
        #time.sleep(0.001)

'''
def asc():
    setup(255,255,0)
    for f in range(60, 128, 1):
        for k in range(7,-1,-1):
            for x in range(5):
                for y in range(5):
                    if get_bit(num[f * 5 + x], y):
                        point2(y+k*6, 4-x, color[5])
                    else:
                        point2(y+k*6, 4-x, color[2])
            
            f += 1
            if f > 255:
                break
        np.write()
        time.sleep(0.6)

def sync_time():
    ntptime.NTP_DELTA = 3155644800  # 东八区时间偏移量（秒）
    ntptime.host = 'ntp1.aliyun.com'  # 使用阿里云的NTP服务器
    try:
        print('Syncing time...')
        ntptime.settime()
        print('Time sync successful')
    except Exception as e:
        print('Time sync failed:', e)

def get_time():
    rtc = machine.RTC()
    current_time = rtc.datetime()
    # 格式化为00:00:00
    formatted_time = "{:02d}:{:02d}:{:02d}".format(current_time[4], current_time[5], current_time[6])
    return formatted_time


def show_time():
    #setup(255,255,0)

    for i in range(0, 8, 1):
        f = ord(t[i])
        for x in range(5):
            for y in range(5):
                if  get_bit(num[f * 5 + x], y):
                    #point2(y+i*6, 4-x, color[7-(i+k)%8])
                    point2(y+i*6, 4-x+0, color[7-(i+k)%8])
                else:
                    #point2(y+i*6, 4-x, color[9])
                    point2(y+i*6, 4-x+0, color[9])
    #np.write()
    #time.sleep(0.1)
s = "-MSCODE-"
def show_text():
    for i in range(0, 8, 1):
        f = ord(s[i])
        for x in range(5):
            for y in range(5):
                if  get_bit(num[f * 5 + x], y):
                    point2(y+i*6, 4-x+6, color[4])
                else:
                    point2(y+i*6, 4-x+6, color[9])
    #np.write()
    #time.sleep(0.1)

# 主程序
sync_time()
setup(0,0,0)
time.sleep(1)
sync_time()
setup(0,0,0)
time.sleep(1)
while True:
    #np.fill((0, 0, 0))
    #loop()
    #asc()
    t = get_time()
    k = int(t[6:])
    show_time()
    show_text()
    np.write()
    time.sleep(0.1)
    
